package wang.chunfan.springcloud.learning.sentinel.server.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import wang.chunfan.springcloud.learning.sentinel.server.model.Result;
import wang.chunfan.springcloud.learning.sentinel.server.model.User;

/**
 * @version 1.0
 * @Author wangchunfan
 * @Date 2020/5/27 18:00
 **/
@RestController
@RequestMapping("/circle-breaker")
public class CircleBreakerController {
    private static final Logger LOGGER = LoggerFactory.getLogger(CircleBreakerController.class);

    @Autowired
    private RestTemplate restTemplate;

    @Value("${server-url.nacos-user-server}")
    private String userServerUrl;

    /**
     * 服务降级，所有异常都降级
     */
    @GetMapping("/fallback/{id}")
    @SentinelResource(value = "fallback", fallback = "handleFallback")
    public Result<User> fallback(@PathVariable Long id) {
        Result<User> user = restTemplate.getForObject(userServerUrl + "/user/{1}", Result.class, id);
        LOGGER.info(user.toString());
        return user;
    }


    public Result handleFallback(Long id) {
        return new Result("服务降级返回", 200);
    }

    /**
     * 服务降级忽略指定异常
     */
    @GetMapping("/fallbackException/{id}")
    @SentinelResource(value = "fallbackException",
            fallback = "handleFallback2",
            exceptionsToIgnore = {NullPointerException.class})
    public Result fallbackException(@PathVariable Long id) {
        if (id == 1) {
            throw new IndexOutOfBoundsException();
        } else if (id == 2) {
            throw new NullPointerException();
        }

        return restTemplate.getForObject(userServerUrl + "/user/{1}", Result.class, id);
    }

    public Result handleFallback2(Long id, Throwable e) {
        LOGGER.error("handleFallback2 id:{},throwable class:{}", id, e.getClass());
        return new Result("忽略异常，服务降级返回", 200);
    }
}
